import type {
  ComponentRecordType,
  GenerateMenuAndRoutesOptions,
  RouteRecordStringComponent,
} from '@vben/types';

import type { Router } from '#/api';

import { generateAccessible } from '@vben/access';
import { preferences } from '@vben/preferences';

import { ElMessage } from 'element-plus';

import { getRouterApi } from '#/api';
import { BasicLayout, IFrameView } from '#/layouts';
import { $t } from '#/locales';

import { localMenuList } from './routes/static/local';

const forbiddenComponent = () => import('#/views/_core/fallback/forbidden.vue');

async function generateAccess(options: GenerateMenuAndRoutesOptions) {
  const pageMap: ComponentRecordType = import.meta.glob('../views/**/*.vue');

  const layoutMap: ComponentRecordType = {
    BasicLayout,
    IFrameView,
  };

  /**
   * 后台路由转vben路由
   *
   * @param routers 后台菜单
   * @returns vben路由
   */
  function backMenuToVbenMenu(routers: Router[]): RouteRecordStringComponent[] {
    const resultList: RouteRecordStringComponent[] = [];
    routers.forEach((router) => {
      const vbenRoute: RouteRecordStringComponent = {
        component: router.component,
        meta: {
          // 当前路由不在菜单显示 但是可以通过链接访问
          // 不可访问的路由由后端控制隐藏(不返回对应路由)
          hideInMenu: router.meta?.hidden,
          icon: router.meta?.icon,
          keepAlive: router.meta?.keepAlive,
          title: router.meta?.title,
          query: router.meta?.query,
          badge: 'new',
          badgeType: 'normal',
          badgeVariants: 'primary',
        },
        name: router.name,
        path: router.path,
      };

      // 转换组件对应属性
      switch (vbenRoute.component) {
        case 'IFrameView': {
          if (vbenRoute.meta) {
            vbenRoute.meta.iframeSrc = router.meta?.link;
          }
          break;
        }
        case 'link': {
          if (vbenRoute.meta) {
            vbenRoute.meta.link = router.meta?.link;
          }
          vbenRoute.component = '';
          break;
        }
        default: {
          break;
        }
      }

      // children处理
      if (router.children && router.children.length > 0) {
        vbenRoute.children = backMenuToVbenMenu(router.children);
      }

      resultList.push(vbenRoute);
    });

    return resultList;
  }

  return await generateAccessible(preferences.app.accessMode, {
    ...options,
    fetchMenuListAsync: async () => {
      ElMessage({
        duration: 1500,
        message: `${$t('common.loadingMenu')}...`,
      });
      const backMenuList = await getRouterApi();
      // 转换为vben能用的路由
      const vbenMenuList = backMenuToVbenMenu(backMenuList);

      // 特别注意 这里要深拷贝
      const menuList = [...structuredClone(localMenuList), ...vbenMenuList];
      return menuList;
    },
    // 可以指定没有权限跳转403页面
    forbiddenComponent,
    // 如果 route.meta.menuVisibleWithForbidden = true
    layoutMap,
    pageMap,
  });
}

export { generateAccess };
